/**
 * 
 */
package model.database;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import model.entity.Levels;

/**
 * @author heroandtn3
 * 
 */
public class LevelDB {

	private Connection conn;
	private PreparedStatement preSt;
	private LevelFile lvFile = new LevelFile(); 

	/**
	 * 
	 */
	public LevelDB() {
		// TODO Auto-generated constructor stub
		this.conn = ConnectDB.getConn();
	}

	public int getCountLevel() {
		int c = 0;
		try {
			preSt = conn
					.prepareStatement("SELECT COUNT(*) AS count FROM `levels`");
			ResultSet rs = preSt.executeQuery();
			if (rs.next())
				c = rs.getInt("count");
		} catch (SQLException e) {
			//e.printStackTrace();
		}
		return c;
	}

	public Levels getLevelByID(int id) {
		Levels lg = null;
		try {
			preSt = conn.prepareStatement("SELECT * FROM `levels` WHERE `id` = ?;");
			preSt.setInt(1, id);
			ResultSet rs = preSt.executeQuery();
			if (rs.next()) {
				lg = new Levels();
				lg.setId(id);
				lg.setName(rs.getString("name"));
				lg.setMatrix(lvFile.readFromFile(id));
			}

		} catch (SQLException e) {
			//e.printStackTrace();
		}
		return lg;
	}

	public List<Levels> getAllLevelByMapID(int id) {
		List<Levels> lList = null;
		try {
			preSt = conn.prepareStatement("SELECT * FROM `levels` WHERE mapID = ?");
			preSt.setInt(1, id);
			ResultSet rs = preSt.executeQuery();
			lList = new ArrayList<Levels>();
			while (rs.next()) {
				Levels lg = new Levels();
				lg.setId(rs.getInt("id"));
				lg.setName(rs.getString("name"));
				lg.setMatrix(lvFile.readFromFile(rs.getInt("id")));
				lList.add(lg);
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
		}

		return lList;
	}
	
	/**
	 * Tra ve so level co dung mapID la id
	 */
	public int getCountLevelByMapID(int id) {
		int count =0;
		try {
			preSt = conn.prepareStatement("SELECT COUNT(*) AS count FROM `levels` WHERE mapID = ?");
			preSt.setInt(1, id);
			ResultSet rs = preSt.executeQuery();
			if (rs.next()) {
				count = rs.getInt("count");
			}
		} catch (SQLException e) {
			//e.printStackTrace();
		}
		return count;
	}
	
	/**
	 * Tra ve id cua level cuoi cung
	 * 
	 */
	private int getLastLevelID() {
		int id = 0;
		try {
			preSt = conn.prepareStatement("SELECT MAX(id) AS max FROM `levels`");
			ResultSet rs = preSt.executeQuery();
			if (rs.next()) {
				id = rs.getInt("max");
			}
		} catch (SQLException e) {
			//e.printStackTrace();
		}
		return id;
	}
	


	public boolean insertLevel(Levels level, int mapId) {
		try {
			preSt = conn.prepareStatement("INSERT INTO levels(name, mapID) VALUES(?, ?);");
			preSt.setString(1, level.getName());
			preSt.setInt(2, mapId);
			if (preSt.executeUpdate() > 0) {
				lvFile.writeToFile(level.getMatrix(), getLastLevelID()); // luu ma tran ra file
				return true;
			}
				
		} catch (SQLException e) {
			//e.printStackTrace();
		}
		return false;
	}

	public boolean deleteLevelByMapID(int id) {
		try {
			preSt = conn.prepareStatement("DELETE FROM `levels` WHERE `mapID` = ?;");
			preSt.setInt(1, id);
			if (preSt.executeUpdate() > 0)
				return true;
		} catch (SQLException e) {
			//e.printStackTrace();
		}
		return false;
	}
	
	class LevelFile {

		/**
		 * Doc va ghi matran level
		 * @author Huan
		 */

		// dua vao ID de doc matran cua level
		// tra ve ma tran cua level tuong ung
		public int[][] readFromFile(int id) {
			int[][] outMatrix = null;
			File fi = new File("data/level/" + id + ".oop");
			int row, col;

			try {
				FileInputStream fis = new FileInputStream(fi);
				BufferedReader br = new BufferedReader(new InputStreamReader(fis));
				String s = new String();
				try {
					s = br.readLine().trim();
					row = new Integer(s);
					s = br.readLine().trim();
					col = new Integer(s);
					outMatrix = new int[row][col];
					for (int i = 0; i < row; i++) {
						s = br.readLine().trim();
						String[] B = s.split(" ");
						for (int j = 0; j < col; j++) {
							outMatrix[i][j] = new Integer(B[j].trim());
						}
					}
					br.close();
				} catch (IOException ex) {
					Logger.getLogger(LevelFile.class.getName()).log(Level.SEVERE,
							null, ex);

				}
			} catch (FileNotFoundException ex) {
				Logger.getLogger(LevelFile.class.getName()).log(Level.SEVERE, null,
						ex);
			}

			return outMatrix;
		}

		public boolean writeToFile(int[][] mt, int id) {
			PrintStream out;
			File fo = new File("data/level/" + id + ".oop");
			int row = mt.length;
			int col = mt[0].length;
			try {
				FileOutputStream fos = new FileOutputStream(fo);
				out = new PrintStream(fos);

				out.println(row);
				out.println(col);

				for (int i = 0; i < row; i++) {
					for (int j = 0; j < col; j++) {
						out.printf("%d ", mt[i][j]);
					}
					out.println();
				}
				out.close();
			} catch (FileNotFoundException ex) {
				Logger.getLogger(LevelFile.class.getName()).log(Level.SEVERE, null,
						ex);
				return false;
			}
			return true;
		}
	}
}
